﻿using System.Windows;
using System.Windows.Media;
using System.Windows.Shapes;

namespace DynamicGeometry
{
    public class ArcBase : ShapeBase<Path>, ILinearFigure
    {

        public string c_store_id { get; set; }
        public string c_guid { get; set; }

        public string c_type { get; set; }
        public bool c_is_modify { get; set; }

        public override void UpdateVisual()
        {
            var radius = ToPhysical(Point(0).Distance(Point(1)));
            ArcShape.Size = new Size(radius, radius);
            Figure.StartPoint = ToPhysical(Point(1));
            ArcShape.Point = ToPhysical(Point(2));
            ArcShape.IsLargeArc = Math.OAngle(Point(1), Point(0), Point(2)) > Math.PI;
        }

        public PathFigure Figure { get; set; }
        public ArcSegment ArcShape { get; set; }

        public override IFigure HitTest(Point point)
        {
            if ((Point(0).Distance(Point(1)) - Point(0).Distance(point)).Abs() >= CursorTolerance)
            {
                return null;
            }
            var result = Math.GetAngle(Point(0), point);
            var a1 = Math.GetAngle(Point(0), Point(1));
            var a2 = Math.GetAngle(Point(0), Point(2));
            if (a2 < a1)
            {
                a2 = 2 * Math.PI + a2;
            }
            return result >= a1 && result <= a2 ? this : null;
        }

        public virtual double GetNearestParameterFromPoint(Point point)
        {
            var result = Math.GetAngle(Point(0), point);
            var a1 = Math.GetAngle(Point(0), Point(1));
            var a2 = Math.GetAngle(Point(0), Point(2));
            if (a2 < a1)
            {
                a2 = 2 * Math.PI + a2;
            }
            if (result < a1)
            {
                result = a1;
            }
            else if (result > a2)
            {
                result = a2;
            }
            if (result > 2 * Math.PI)
            {
                result -= 2 * Math.PI;
            }
            return result;
        }

        public virtual Point GetPointFromParameter(double parameter)
        {
            var center = Point(0);
            var radius = Point(0).Distance(Point(1));
            return new Point(
                center.X + radius * System.Math.Cos(parameter),
                center.Y + radius * System.Math.Sin(parameter));
        }

        public virtual Tuple<double, double> GetParameterDomain()
        {
            var a1 = Math.GetAngle(Point(0), Point(1));
            var a2 = Math.GetAngle(Point(0), Point(2));
            return Tuple.Create(0.0, 2 * DynamicGeometry.Math.PI);
        }

        protected override Path CreateShape()
        {
            ArcShape = new ArcSegment()
            {
                SweepDirection = SweepDirection.Counterclockwise,
                RotationAngle = 0
            };
            Figure = new PathFigure()
            {
                IsClosed = false,
                IsFilled = false,
                Segments = new PathSegmentCollection()
                {
                    ArcShape
                }
            };
            return new Path()
            {
                Data = new PathGeometry()
                {
                    Figures = new PathFigureCollection()
                    {
                        Figure
                    }
                },
                Stroke = new SolidColorBrush(Colors.Black),
                StrokeThickness = 1
            };
        }
    }
}
